package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"gitee.com/general252/rtmp_rtsp_server/rtmp_server"
	"gitee.com/general252/rtmp_rtsp_server/rtsp_repush"
	"gitee.com/general252/rtmp_rtsp_server/rtsp_server"
)

func init() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
}

var (
	rtmpPort = 1935
	rtspPort = 554
	rtpPort  = 8000
	rtcpPort = rtpPort + 1
	httpPort = 80
)

func main() {
	ctx, ctxFunc := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)

	rtmpServer := rtmp_server.NewServer(rtmpPort)
	rtspServer := rtsp_server.NewServer(rtspPort, rtpPort, rtcpPort)

	go func() {
		defer ctxFunc()

		rtmpServer.OnPush = func(ctx context.Context, path string) {
			go func() {
				time.Sleep(time.Second)

				inputURI := fmt.Sprintf("rtmp://127.0.0.1:%v%v", rtmpPort, path)
				outputURI := fmt.Sprintf("rtsp://127.0.0.1:%v%v", rtspPort, path)

				log.Printf("转流: %v --> %v", inputURI, outputURI)
				_ = rtsp_repush.RtmpToRtsp(ctx, inputURI, outputURI)
			}()
		}
		log.Printf("rtmp server is ready on: %v", rtmpPort)
		log.Println(rtmpServer.Serve())
	}()

	go func() {
		defer ctxFunc()

		rtspServer.Handler.OnPush = func(ctx context.Context, path string) {
			log.Println(path)
			if !strings.HasSuffix(path, "2") {
				go func() {
					time.Sleep(time.Second)

					inputURI := fmt.Sprintf("rtsp://127.0.0.1:%v%v", rtspPort, path)
					outputURI := fmt.Sprintf("rtsp://127.0.0.1:%v%v2", rtspPort, path)

					log.Printf("转流: %v --> %v", inputURI, outputURI)
					_ = rtsp_repush.RePush(ctx, inputURI, outputURI)
				}()
			}
		}
		log.Printf("rtsp server is ready on: %v", rtspPort)
		log.Println(rtspServer.Serve())
	}()

	go func() {
		type JsonSession struct {
			RtmpList []string `json:"rtmp_list"`
			RtspList []string `json:"rtsp_list"`
		}

		http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			data, _ := json.MarshalIndent(JsonSession{
				RtmpList: rtmpServer.GetSessionList(),
				RtspList: rtspServer.GetSessionList(),
			}, "", "  ")
			_, _ = w.Write(data)
		})

		log.Printf("http server is ready on: %v", httpPort)
		log.Println(http.ListenAndServe(fmt.Sprintf(":%v", httpPort), nil))
	}()

	<-ctx.Done()
}
